import { render, createVNode } from 'vue';
import ModelLogin from './ModelLogin.vue';
import ModelRegister from './ModelRegister.vue';
import ModelResetPwd from './ModelResetPwd.vue';
import { isClient } from '@vueuse/core';
import { hasOwn } from '@vue/shared';
import { ElMessageBox } from 'element-plus';

export const messageInstance = new Map();
const initInstance = ({ props, container, appContext = null, modelType = 'ModelLogin' }) => {
  let Com: any = null;
  if (modelType === 'ModelResetPwd') {
    Com = ModelResetPwd;
  } else if (modelType === 'ModelRegister') {
    Com = ModelRegister;
  } else {
    Com = ModelLogin;
  }
  const vnode = createVNode(Com, props);
  vnode.appContext = appContext;
  render(vnode, container);
  document.body.appendChild(container);
  return vnode.component;
};
const genContainer = () => {
  const container = document.createElement('div');
  container.className = `modal_box__wrapper`;
  return container;
};
const showModel = (
  options = {},
  modelType: 'ModelLogin' | 'ModelResetPwd' | 'ModelRegister',
  appContext,
) => {
  const container = genContainer();
  const instance: any = initInstance({ props: options, container, appContext, modelType });
  const vm = instance.proxy;
  for (const prop in options) {
    if (hasOwn(options, prop) && !hasOwn(vm.$props, prop)) {
      vm[prop] = options[prop];
    }
  }
  vm?.openModel();
  return vm;
};

function openLoginBox(options, appContext = null) {
  if (!isClient) return Promise.reject();
  return new Promise((resolve, reject) => {
    const vm = showModel(
      options,
      'ModelLogin',
      appContext != null ? appContext : ElMessageBox._context,
    );
    console.log(vm, '--------');
    messageInstance.set(vm, {
      options,
      resolve,
      reject,
    });
  });
}

function openModelRegister(options, appContext = null) {
  if (!isClient) return Promise.reject();
  return new Promise((resolve, reject) => {
    const vm = showModel(
      options,
      'ModelRegister',
      appContext != null ? appContext : ElMessageBox._context,
    );
    // console.log(vm, '--------');
    messageInstance.set(vm, {
      options,
      resolve,
      reject,
    });
  });
}

function openModelResetPwd(options, appContext = null) {
  if (!isClient) return Promise.reject();
  return new Promise((resolve, reject) => {
    const vm = showModel(
      options,
      'ModelResetPwd',
      appContext != null ? appContext : ElMessageBox._context,
    );
    // console.log(vm, '--------');
    messageInstance.set(vm, {
      vm,
      options,
      resolve,
      reject,
    });
  });
}

const closeAll = () => {
  messageInstance.forEach((_, { vm }) => {
    vm.closeModel();
  });
  messageInstance.clear();
};

openLoginBox.close = closeAll;
openModelRegister.close = closeAll;
openModelResetPwd.close = closeAll;

export { openLoginBox, openModelRegister, openModelResetPwd, closeAll };
